package cn.parus.service.Impl;

import cn.parus.common.Execption.CustomException;
import cn.parus.constants.FileTypeConstants;
import cn.parus.entity.FileMetadata;
import cn.parus.mapper.FileMetadataMapper;
import cn.parus.service.FileMetadataService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: Axel
 * @Description: TODO
 **/
@Service
public class FileMetadataServiceImpl extends ServiceImpl<FileMetadataMapper, FileMetadata> implements FileMetadataService {

    @Override
    public Page<FileMetadata> searchFileMetadata(String filePath, String ownerId, Integer current, Integer size, String status, String fileType) {
        // 参数校验：ownerId 必须存在
        if (StringUtils.isBlank(ownerId)) {
            throw new CustomException("查询文件时，用户ID不能为空");
        }

        Page<FileMetadata> page = new Page<>(current, size);
        LambdaQueryWrapper<FileMetadata> queryWrapper = new LambdaQueryWrapper<>();

        // 强制校验用户ID和状态（固定条件）
        queryWrapper.eq(FileMetadata::getOwnerId, ownerId)
                    .eq(FileMetadata::getStatus, status);

        // 文件类型过滤（使用常量提升可读性）
        if (StringUtils.isNotBlank(fileType)) {
            switch (fileType) {
                case FileTypeConstants.FILE_TYPE_PICTURE:
                    queryWrapper.in(FileMetadata::getFileType, FileTypeConstants.PICTURE_FORMATS);
                    break;
                case FileTypeConstants.FILE_TYPE_VIDEO:
                    queryWrapper.in(FileMetadata::getFileType, FileTypeConstants.VIDEO_FORMATS);
                    break;
                case FileTypeConstants.FILE_TYPE_DOCUMENT:
                    queryWrapper.in(FileMetadata::getFileType, FileTypeConstants.DOCUMENT_FORMATS);
                    break;
                default:
                    queryWrapper.eq(FileMetadata::getFileType, fileType);
            }
        }

        // 路径匹配优化：简化条件判断逻辑
        if ("all".equals(filePath)) {
            // 查询所有路径时不添加路径条件
        } else if (StringUtils.isNotBlank(filePath)) {
            queryWrapper.eq(FileMetadata::getFilePath, filePath);
        } else {
            // 处理根目录场景（兼容null和"/"两种存储方式）
            queryWrapper.and(wrapper -> wrapper.isNull(FileMetadata::getFilePath).or().eq(FileMetadata::getFilePath, "/"));
        }

        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createNewFolder(FileMetadata fileMetadata) {
        // 参数校验
        if (StringUtils.isBlank(fileMetadata.getFilePath()) || StringUtils.isBlank(fileMetadata.getOwnerId())) {
            throw new CustomException("文件夹路径或所属用户ID不能为空");
        }
        if (StringUtils.isBlank(fileMetadata.getFileName())) {
            throw new CustomException("文件夹名称不能为空");
        }

        // 重名校验：同路径下不能有同名文件夹
        LambdaQueryWrapper<FileMetadata> duplicateQuery = new LambdaQueryWrapper<>();
        duplicateQuery.eq(FileMetadata::getFilePath, fileMetadata.getFilePath())
                .eq(FileMetadata::getOwnerId, fileMetadata.getOwnerId())
                .eq(FileMetadata::getFileName, fileMetadata.getFileName())
                .eq(FileMetadata::getFileType, "folder"); // 假设文件夹类型标记为"folder"

        if (baseMapper.exists(duplicateQuery)) {
            throw new CustomException("当前目录下已存在同名文件夹");
        }

        this.save(fileMetadata);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createNewFile(FileMetadata fileMetadata) {
        // 参数校验
        if (StringUtils.isBlank(fileMetadata.getFilePath()) || StringUtils.isBlank(fileMetadata.getOwnerId())) {
            throw new CustomException("文件路径或所属用户ID不能为空");
        }
        if (StringUtils.isBlank(fileMetadata.getFileName())) {
            throw new CustomException("文件名不能为空");
        }
        if (fileMetadata.getFileSize() == null || fileMetadata.getFileSize() <= 0) {
            throw new CustomException("文件大小不合法");
        }

        // 重名校验：同路径下不能有同名文件
        LambdaQueryWrapper<FileMetadata> duplicateQuery = new LambdaQueryWrapper<>();
        duplicateQuery.eq(FileMetadata::getFilePath, fileMetadata.getFilePath())
                .eq(FileMetadata::getOwnerId, fileMetadata.getOwnerId())
                .eq(FileMetadata::getFileName, fileMetadata.getFileName())
                .eq(FileMetadata::getIsDirectory, false); // 仅检查非目录文件

        if (baseMapper.exists(duplicateQuery)) {
            throw new CustomException("当前目录下已存在同名文件");
        }

        this.save(fileMetadata);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDocument(String fileId) {
        // 参数校验
        if (StringUtils.isBlank(fileId)) {
            throw new CustomException("删除文件时，文件ID不能为空");
        }

        // 检查文件是否存在
        FileMetadata existFile = baseMapper.selectById(fileId);
        if (existFile == null) {
            throw new CustomException("文件不存在，删除失败");
        }

        // 级联删除：如果是文件夹，删除其下所有子文件/子文件夹
        if ("folder".equals(existFile.getFileType())) {
            String folderPath = existFile.getFilePath() + existFile.getFileId() + "/";
            LambdaQueryWrapper<FileMetadata> childQuery = new LambdaQueryWrapper<>();
            childQuery.like(FileMetadata::getFilePath, folderPath); // 匹配子路径
            baseMapper.delete(childQuery);
        }

        // 删除当前文件
        this.removeById(fileId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDocument(FileMetadata fileMetadata) {
        // 1. 参数校验
        if (fileMetadata == null || StringUtils.isBlank(fileMetadata.getFileId())) {
            throw new CustomException("更新文件信息时，文件ID不能为空");
        }
    
        // 2. 检查文件是否存在
        LambdaQueryWrapper<FileMetadata> existQuery = new LambdaQueryWrapper<>();
        existQuery.eq(FileMetadata::getFileId, fileMetadata.getFileId());
        FileMetadata existFile = baseMapper.selectOne(existQuery);
        if (existFile == null) {
            throw new CustomException("更新失败，文件ID为 " + fileMetadata.getFileId() + " 的文件不存在");
        }
    
        // 3. 构建更新条件（仅更新非空字段，避免覆盖原有有效数据）
        LambdaQueryWrapper<FileMetadata> updateQuery = new LambdaQueryWrapper<>();
        updateQuery.eq(FileMetadata::getFileId, fileMetadata.getFileId());
    
        // 4. 执行更新（使用 MyBatis-Plus 的 update 方法，仅更新非空字段）
        boolean updateResult = this.update(fileMetadata, updateQuery);
        if (!updateResult) {
            throw new CustomException("文件信息更新失败");
        }
    
        // 新增：级联更新子目录状态（仅当更新的是文件夹且传入了新status时生效）
        String newStatus = fileMetadata.getStatus();
        if (StringUtils.isNotBlank(newStatus) && "folder".equals(existFile.getFileType())) {
            // 构造子目录路径（格式：父路径 + 父文件ID + "/"）
            String parentFolderPath = existFile.getFilePath() + existFile.getFileId() + "/";
            LambdaQueryWrapper<FileMetadata> childQuery = new LambdaQueryWrapper<>();
            childQuery.like(FileMetadata::getFilePath, parentFolderPath);  // 匹配子目录路径
    
            // 批量更新子目录的status
            FileMetadata updateChild = new FileMetadata();
            updateChild.setStatus(newStatus);
            this.update(updateChild, childQuery);
        }
    }
}
